<template>
  <div id="bigBox" class="bigBox">
    <!-- 窗口上方导航栏 -->
    <div id="naviBar" class="naviBar">
      <div class="naviBarTitle"><a href="http://localhost:8082/">Cesium Demo</a></div>
      <div id="naviBarAddWMS" class="naviBarItem">添加WMS</div>
      <div id="naviBarAddWMTS" class="naviBarItem">添加WMTS</div>
      <div id="naviBarAddWFS" class="naviBarItem">添加WFS</div>
      <div id="naviBarAddTMS" class="naviBarItem">添加TMS</div>
      <div id="naviBarAdd3DTiles" class="naviBarItem">添加3DTiles</div>
      <div id="naviBarAddWTerrain" class="naviBarItem">添加Terrain</div>
    </div>
    <!-- 窗口左侧图层列表 -->
    <div id="left-LayerList" class="left-LayerList">
      <ul id="left-LayerListUl">
        <div class="left-LayerListTitle">图层列表</div>
        <li class="left-LayerListItem">测试
          <div class="left-LayerListItemDel" title="图层删除"><i id="left-LayerListLayerDelBtn" class="bi bi-trash3"></i>
          </div>
          <div class="left-LayerListItemShow" title="图层显隐"><i id="left-LayerListLayerShowBtn" class="bi bi-eye-slash"></i>
          </div>
        </li>
      </ul>
    </div>
    <!-- cesium -->
    <div id="cesiumContainer"></div>
    <!-- 图层添加结果(成功/失败) -->
    <div id="liveAlertPlaceholder" class="liveAlertPlaceholder"></div>
    <!-- 图层添加表单 -->
    <div id="layerAddForm" class="layerAddForm">
      <!-- 标题 -->
      <div class="layerAddFormTitle">
        <label>图层添加</label>
        <i class="bi bi-x layerAddFormClose" id="layerAddFormClose"></i>
      </div>
      <!-- 服务地址 -->
      <div class="mb-3 row inputDiv">
        <label for="inputURL" class="col-sm-2 col-form-label ">服务地址:</label>
        <div class="col-sm-10">
          <input type="text" class="form-control inputInput" id="inputURL">
        </div>
        <button id="getLayerBtn" class="getLayerBtn">...</button>
      </div>
      <!-- Layername -->
      <div id="layerNameDiv" class="mb-3 row inputDiv">
        <label for="inputLayer" class="col-sm-2 col-form-label ">Layername:</label>
        <div class="col-sm-10">
          <input type="text" class="form-control inputInput" id="inputLayer">
        </div>
      </div>
      <!-- 图层名称 -->
      <div class="mb-3 row inputDiv">
        <label for="inputLayername" class="col-sm-2 col-form-label ">图层名称:</label>
        <div class="col-sm-10">
          <input type="text" class="form-control inputInput" id="inputLayername">
        </div>
      </div>
      <div class="btnGroup">
        <button type="button" class="btn btn-secondary btn-sm btnItem01" id="addLayerBtn">添加</button>
        <button type="button" class="btn btn-secondary btn-sm btnItem02" id="cancelLayerBtn">取消</button>
      </div>
    </div>
  </div>
</template>
<script setup>
import { onMounted } from 'vue'
import * as Cesium from 'cesium'
import './main.css'
import { Viewer } from 'cesium';
import proj4 from 'proj4'
Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0Y2YxYWFiOC1hMjkxLTQ3MmQtOTMzOC02ODQzNGYzZThjYmIiLCJpZCI6MTg0MTQwLCJpYXQiOjE3MDI0NDY4MDR9.Xax9xESQVAXXQgP_6OnWSj0AAvpwFh_FLQAxjdwfaZ0"
onMounted(async () => {
  // 地球视图，底图加载
  const viewer = new Cesium.Viewer('cesiumContainer', {
    //地形图层
    terrain: Cesium.Terrain.fromWorldTerrain(),
    //信息窗口
    infoBox: false,
    //显示查询按钮
    // geocoder: false,
    //home按钮
    homeButton: false,
    //控制查看器的显示模式
    sceneModePicker: false,
    // 是否显示图层选择
    baseLayerPicker: false,
    //帮助按钮
    navigationHelpButton: false,
    //播放动画
    animation: false,
    //时间线
    timeline: false,
    //全屏模式
    fullscreenButton: false,
    //

  });
  viewer.extend(Cesium.viewerCesiumInspectorMixin);
  // cesium基本设置
  function cesiumDefaultModel(viewer) {
    //隐藏cesium Icon-logo
    viewer.cesiumWidget.creditContainer.style.display = 'none';
    //帧率
    viewer.scene.debugShowFramesPerSecond = true;
    // cesium的默认视角
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(89.5, 20.4, 110.4, 61.2);
    // 抗锯齿
    viewer.scene.fxaa = true;
    viewer.scene.postProcessStages.fxaa.enabled = false;
    // 水雾特效
    viewer.scene.globe.showGroundAtmosphere = true;
    // 设置最大俯仰角，[-90,0]区间内，默认为-30，单位弧度
    viewer.scene.screenSpaceCameraController.constrainedPitch = Cesium.Math.toRadians(-20);
    viewer.scene.screenSpaceCameraController.autoResetHeadingPitch = false;
    viewer.scene.screenSpaceCameraController.inertiaZoom = 0.5;
    //设置缩放程度
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 50;
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 30000000;
    //设置视角缩放类型
    //设置鼠标操作
    viewer.scene.screenSpaceCameraController.zoomEventTypes = [
      Cesium.CameraEventType.RIGHT_DRAG,
      Cesium.CameraEventType.WHEEL,
      Cesium.CameraEventType.PINCH,
    ];
    viewer.scene.screenSpaceCameraController.tiltEventTypes = [
      Cesium.CameraEventType.MIDDLE_DRAG,
      Cesium.CameraEventType.PINCH,
      {
        eventType: Cesium.CameraEventType.LEFT_DRAG,
        modifier: Cesium.KeyboardEventModifier.CTRL,
      },
      {
        eventType: Cesium.CameraEventType.RIGHT_DRAG,
        modifier: Cesium.KeyboardEventModifier.CTRL,
      },
    ];
    //地形夸张 拉伸地形
    // viewer.scene.globe.terrainExaggeration = 1.0;
    //添加OMS 房屋
    // viewer.scene.primitives.add(await Cesium.createOsmBuildingsAsync())
    //添加瓦片坐标信息
    // viewer.imageryLayers.addImageryProvider(new Cesium.TileCoordinatesImageryProvider())
    // 将三维球定位到中国
    viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(103.84, 31.15, 17850000),
      orientation: {
        heading: Cesium.Math.toRadians(348.4202942851978),
        pitch: Cesium.Math.toRadians(-89.74026687972041),
        roll: Cesium.Math.toRadians(0)
      },
      complete: function callback() {
        // 定位完成之后的回调函数
      }
    });
  }
  cesiumDefaultModel(viewer); //调用方法
  // WFS坐标转换
  Cesium.GeoJsonDataSource.crsNames['urn:ogc:def:crs:EPSG::4490'] =
    Cesium.GeoJsonDataSource.crsNames['EPSG:4490'] = coordinates => {
      const fromProjection = `GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]`
      const toProjection = `GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]`

      const x = coordinates[0]
      const y = coordinates[1]

      const newCoordinates = proj4(fromProjection, toProjection, [x, y])
      return Cesium.Cartesian3.fromDegrees(
        newCoordinates[0],
        newCoordinates[1],
        0
      )
    }

  //添加WMS方法 传入url 和 图层名称
  function addWMS(layerInputUrl, layerInputLayer) {
    viewer.imageryLayers.addImageryProvider(
      new Cesium.WebMapServiceImageryProvider({
        url: layerInputUrl,
        layers: layerInputLayer,
        parameters: {
          format: 'image/png',
          transparent: true,
          style: ''
        }
      })
    )
  }
  //添加WMTS方法 传入url 和 图层名称
  function addWMTS(layerInputUrl, layerInputLayer) {
    viewer.imageryLayers.addImageryProvider(
      new Cesium.WebMapTileServiceImageryProvider({
        url: layerInputUrl,
        layers: layerInputLayer,
        style: "default",
        format: "image/jpeg",
        tileMatrixSetID: "EPSG:4326"
      })
    )
  }
  //添加WFS方法 传入url
  function addWFS(layerInputUrl) {
    let dataWFS = Cesium.GeoJsonDataSource.load(layerInputUrl + "&outputformat=application/json", {
      stroke: Cesium.Color.PINK,  //边界颜色
      fill: Cesium.Color.RED,   //填充颜色
      show: true
    });
    dataWFS.then(function (data) {
      viewer.dataSources.add(data);
      viewer.flyTo(data);
    })
  }
  //添加TMS 传入url
  function addTMS(layerInputUrl) {
    viewer.imageryLayers.addImageryProvider(
      new Cesium.UrlTemplateImageryProvider({
        url: layerInputUrl + "/{z}/{x}/{y}.png",
      })
    )
  }
  //添加3DTiles 传入url
  function add3DTiles(layerInputUrl) {
    Cesium.Cesium3DTileset.fromUrl(layerInputUrl).then((tileset) => {
      viewer.scene.primitives.add(tileset);
      viewer.zoomTo(tileset);
    })
      .catch((error) => {
        addLayerFail(alertPlaceholder);
        console.log(error);
      })
  }
  //添加Terrain 传入url
  function addTerrain(layerInputUrl) {
    Cesium.CesiumTerrainProvider.fromUrl(layerInputUrl, {
      requestWaterMask: true,
      requestVertexNormals: true,
    }).then((TerrainProvider) => {
      Viewer.TerrainProvider = TerrainProvider;
    })
  }

  // ...快速获取公司地址layer内容 方法
  function layerToName(layerInputUrl) {
    let layer = layerInputUrl.split("%3A");
    if (layer[1]) {
      return layer[1]
    }

  }

  var addLayerTypeFlag = 0;
  // 获取 添加图层表单
  const layerAddForm = document.getElementById("layerAddForm");
  // 获取url layer name
  var layerInputUrl = document.getElementById("inputURL");
  var layerInputLayer = document.getElementById("inputLayer");
  var layerInputName = document.getElementById("inputLayername");
  //获取left-list中的ul
  var left_ListUl = document.getElementById("left-LayerListUl");
  // 获取添加图层表单 添加按钮
  var addLayerBtn = document.getElementById("addLayerBtn");
  addLayerBtn.addEventListener('click', function () {
    addLayerPac(addLayerTypeFlag);
  })
  // 获取layername输入整个div
  var layerNameDiv = document.getElementById("layerNameDiv");

  //图层添加方法整合
  function addLayerPac(flag) {
    let layersCount = viewer.imageryLayers._layers.length;
    if (flag == 1) {
      addWMS(layerInputUrl.value, layerInputLayer.value);
    }
    else if (flag == 2) {
      addWMTS(layerInputUrl.value, layerInputLayer.value);
    }
    else if (flag == 3) {
      addWFS(layerInputUrl.value);
    }
    else if (flag == 4) {
      addTMS(layerInputUrl.value);
    }
    else if (flag == 5) {
      add3DTiles(layerInputUrl.value);
    }
    else {
      addTerrain(layerInputUrl.value);
    }
    listFlag++;
    addLayerSuccess(alertPlaceholder);
    addListLayer(left_ListUl);
    close(layerAddForm, layerInputUrl, layerInputLayer, layerInputName);
  }
  // 控制 layer和...输入条件 
  function layerCantWrite(i) {
    // console.log(i);
    if (i >= 3) {
      layerNameDiv.style.display = "none";
      getLayerBtn.style.display = "none";
    }
    else if (i < 3) {
      layerNameDiv.style.display = "flex";
      getLayerBtn.style.display = "block";
    }
  }
  // 获取 ...快速获取公司地址layer内容
  var getLayerBtn = document.getElementById("getLayerBtn");
  getLayerBtn.addEventListener('click', function () {
    layerInputLayer.value = layerToName(layerInputUrl.value, layerInputLayer.value);
  })

  //添加图层
  //添加WMS
  var naviAddWMS = document.getElementById("naviBarAddWMS");
  naviAddWMS.addEventListener('click', function () {
    clickInvalid(alertPlaceholder, 1);
    layerCantWrite(addLayerTypeFlag);
    show(layerAddForm);
  })
  //添加WMTS
  var naviAddWMTS = document.getElementById("naviBarAddWMTS");
  naviAddWMTS.addEventListener('click', function () {
    clickInvalid(alertPlaceholder, 2);
    layerCantWrite(addLayerTypeFlag);
    show(layerAddForm);
  })
  //添加WFS
  var naviAddWFS = document.getElementById("naviBarAddWFS");
  naviAddWFS.addEventListener('click', function () {
    clickInvalid(alertPlaceholder, 3);
    layerCantWrite(addLayerTypeFlag);
    show(layerAddForm);
  })
  //添加TMS
  var naviAddTMS = document.getElementById("naviBarAddTMS");
  naviAddTMS.addEventListener('click', function () {
    clickInvalid(alertPlaceholder, 4);
    layerCantWrite(addLayerTypeFlag);
    show(layerAddForm);
  })
  //添加3DTiles
  var naviAdd3DTiles = document.getElementById("naviBarAdd3DTiles");
  naviAdd3DTiles.addEventListener('click', function () {
    clickInvalid(alertPlaceholder, 5);
    layerCantWrite(addLayerTypeFlag);
    show(layerAddForm);
  })
  //添加Terrain
  var naviAddWTerrain = document.getElementById("naviBarAddWTerrain");
  naviAddWTerrain.addEventListener('click', function () {
    clickInvalid(alertPlaceholder, 6);
    layerCantWrite(addLayerTypeFlag);
    show(layerAddForm);
  })

  const alertPlaceholder = document.getElementById('liveAlertPlaceholder')// 获取添加图层结果

  const layerAddFormClose = document.getElementById("layerAddFormClose");// 获取 添加图层表单 关闭按钮
  layerAddFormClose.addEventListener('click', function () {
    close(layerAddForm, layerInputUrl, layerInputLayer, layerInputName);
  })

  const cancelLayerBtn = document.getElementById("cancelLayerBtn");// 获取 添加图层表单 取消按钮
  cancelLayerBtn.addEventListener('click', function () {
    close(layerAddForm, layerInputUrl, layerInputLayer, layerInputName);
  })

  // 关闭 元素显示 方法
  function close(item, url, layer, name) {
    url.value = '';
    layer.value = '';
    name.value = '';
    addLayerTypeFlag = 0;
    item.style.display = "none";
  }
  // 显示 元素显示 方法
  function show(item) {
    item.style.display = "block";
  }

  // 点击无效判断
  function clickInvalid(item, int) {
    if (addLayerTypeFlag != 0) {
      item.innerText = "点击无效";
      layerAddResult(item);
    }
    else {
      addLayerTypeFlag = int;
    }
  }
  // 添加成功
  function addLayerSuccess(item) {
    item.innerText = "添加成功";
    layerAddResult(item);
  }
  // 添加失败
  function addLayerFail(item) {
    item.innerText = "添加失败";
    item.style.backgroundcolor = "red";
    item.style.border = "1px solid #8b0000";
    layerAddResult(item);
  }
  // 设置添加图层成功/失败结果框 显示时间长短 方法
  function layerAddResult(item) {
    item.style.display = "block";
    setTimeout(function () {
      item.style.display = "none";
      item.innerText = '';
    }, 2000)
  }

  //left-listlayer添加
  // 问题：
  // 1. 图层在不点击删除前，show是正常的
  // 删除后，会报错，show方法没定义
  // 目前认为是listflag的值被定义到了后一张图层
  // 删除后，listflag的值没变动
  // 而show控制的是前一张
  // get()对应的图层没有了 show无法调用
  // 2. 3dtiles、terrain、wfs目前还不知道在什么接口能查到相应的数量
  // 比如viewer.imageryLayers._layers.length能看到图层数
  // 3dtiles、terrain、wfs不在imageryLayers中
  // 3. GeoJsonDataSource 中有 show/fill/markcolor/stroke
  //    Cesium3DTileset 中有outlineColor/show 
  //    CesiumTerrainProvider 无color/show
  // 可以通过show来控制wfs/3dtiles的显示
  // 但目前还不知道如何调用目标图层的show 没有get()方法
  var listFlag = 0;
  function addListLayer(ul) {
    var layerListLi = document.createElement("li");//添加li
    layerListLi.setAttribute("class", "left-LayerListItem");//给li添加class
    layerListLi.setAttribute("id", "layerListLi" + listFlag);//给li标签添加id
    var layerListDivShow = document.createElement("div");//添加Showdiv
    layerListDivShow.setAttribute("title", "图层显隐");//给showdiv添加title
    layerListDivShow.setAttribute("class", "left-LayerListItemShow");//给showdiv添加class
    var layerListDivDel = document.createElement("div");//添加DelDiv
    layerListDivDel.setAttribute("title", "图层删除");//给deldiv添加title
    layerListDivDel.setAttribute("class", "left-LayerListItemDel");//给deldiv添加class
    var layerShowI = document.createElement("i");//添加Showi
    layerShowI.setAttribute("class", "bi bi-eye-slash");//给show添加bootstrap图标
    layerShowI.setAttribute("id", "left-LayerListLayerShowBtn" + listFlag);//给show添加id
    var layerDelI = document.createElement("i");//添加Deli
    layerDelI.setAttribute("class", "bi-trash3");//给del添加bootstrap图标
    layerDelI.setAttribute("id", "left-LayerListLayerDelBtn" + listFlag);//给del添加id
    var layerListText = document.createTextNode(layerInputName.value);//添加图层名称
    if (layerInputName.value == '') {
      layerListText = document.createTextNode(listFlag);//若name中为空设置为listFlag
    }
    layerListLi.appendChild(layerListText);//向li中添加图层名称
    layerListLi.appendChild(layerListDivDel);//向li中添加Deldiv
    layerListDivDel.appendChild(layerDelI);//向deldiv中添加i
    layerListLi.appendChild(layerListDivShow);//向li中添加Showdiv
    layerListDivShow.appendChild(layerShowI);//向showdiv中添加i
    ul.appendChild(layerListLi);//向ul中添加li
    let layerShowBtn = document.getElementById("left-LayerListLayerShowBtn" + listFlag);//获取显隐按钮
    //图层显隐事件
    layerShowBtn.addEventListener('click', function () {
      if (viewer.imageryLayers.get(listFlag).show == false) {
        viewer.imageryLayers.get(listFlag).show = true;
      }
      else
        viewer.imageryLayers.get(listFlag).show = false;
    });
    let layerDelBtn = document.getElementById("left-LayerListLayerDelBtn" + listFlag);//获取删除按钮
    let layerListLiDel = document.getElementById("layerListLi" + listFlag);//获取需要删除的li
    //图层删除事件
    layerDelBtn.addEventListener('click', function () {
      console.log(layerDelBtn);
      viewer.imageryLayers.remove(viewer.imageryLayers.get(listFlag));
      ul.removeChild(layerListLiDel);
    });

  }

  // wfs服务显隐控制
  // function showWFS() {

  // }


  // --------------------
})
</script>
 
<style scoped></style>